#region Copyright
/// <copyright>
/// Copyright (c) 2007 Ilia Shramko.
/// Released under the terms of the GNU General Public License.
/// </copyright>
#endregion

using System;
using System.Text;

namespace Osh
{
	/// <summary>
	/// Summary description for BinaryReader.
	/// </summary>
	public class BinaryReader : System.IO.BinaryReader
	{
		private Encoding _encoding;

		public BinaryReader(System.IO.Stream stream) : base(stream)
		{
		}

		public BinaryReader(System.IO.Stream stream, Encoding encoding) : base(stream, encoding)
		{
			_encoding = encoding;
		}

		/// <summary>
		/// Reads a string of at most maxLength characters until the \0 character is found.
		/// The stream position will be advanced to maxLength*2 bytes.
		/// </summary>
		/// <param name="maxLength"></param>
		/// <returns></returns>
		public virtual string ReadString(int maxLength)
		{
			// We can't use base.ReadChars() here because the garbage after the \0 character can contain
			// Unicode surrogate code points (see http://www.unicode.org/glossary/#surrogate_code_point)
			// which won't be propely counted and we may exceed the maxLength limit.
			
			byte[] bytes = base.ReadBytes(maxLength * 2);
			char[] chars = _encoding.GetChars(bytes);

			int zeroPos = Array.IndexOf(chars, '\0', 0);
			if(zeroPos == -1)
				return new string(chars);
			else if(zeroPos == 0)
				return string.Empty;
			else
				return new string(chars, 0, zeroPos);
		}

		public virtual ushort ReadUInt16BE()
		{
			ushort v = this.ReadUInt16();
			return (ushort)((v >> 8) | (v << 8));
		}

		public virtual uint ReadUInt32BE()
		{
			uint v = this.ReadUInt32();
			return (uint)((v >> 24) | ((v & 0xFF0000) >> 8) | ((v & 0xFF00) << 8) | (v << 24));
		}

		public virtual void SkipBytes(int count)
		{
			this.BaseStream.Seek(count, System.IO.SeekOrigin.Current);
		}
	}
}
